<?php 
/**
* @package DomBase
* @author Oliver Leisalu
*/
function gotoUrl($url, $time = 0){
	if( headers_sent() === true ) 
		echo "<script> window.location=\"$url\"; </script>";
	else 
		header("Location:" . $url);
}
/**
 * @deprecated 
* @package DomBase
* @author Oliver Leisalu
* @return String
*/
function br2nl( $txt ) {
	$txt = ereg_replace("<br>","", $txt);
	$txt = ereg_replace("<br />","", $txt);
	return $txt;
}
/**
* @package DomBase
* @author Oliver Leisalu
* @return String
*/
function array2String( array $array ) {
	$cont = array();
	foreach( $array as $key => &$element)
		$cont[] = 
				(is_numeric($key) ? $key : '\''.$key.'\'')
				.'=>'. 
				(is_array($element) ? 
							array2String($element) : 
							(is_numeric($element) ? $element : '\''.$element.'\'') );
	return ' array( '.implode(',',$cont).')';
}
/**
 * @deprecated 
* @package DomBase
* @author Oliver Leisalu
*/	
function tac( $mes = '', $nr = 0) {
	try {
		throw new Exception( $mes, $nr );
	} catch( Exception $e ) {
		echo exceptionToString($e);
	}
}
/**
 * @deprecated 
* @package DomBase
* @author Oliver Leisalu
* @return Array
*/
function arrayReOrder( array &$array ) {
	$new = array();
	foreach( $array as $el) $new[] = $el;
	return $new;
}
/**
* @package DomBase
* @author Oliver Leisalu
*/
function intArray( $start, $end) {
	$ar =array();
	for( $i=$start; $i<=$end; $i++) $ar[$i] = $i;
	return $ar;
}

/**
* Merges two arrays and maintaints index associations.
* @package DomBase
* @author Oliver Leisalu
*/
function arrayMerge( array $array, array &$array2 ) {
	foreach( $array2 as $i => &$e) {
		if( is_array($array[$i]) ) {
			$array[$i] = arrayMerge($array[$i], $e);
		} else {
			$array[$i] = $e;
		}
	}
	return $array;
}
/**
 * Flippes array and sets all values to true. Useful for DomFG multiSelects.
 *
 * @param array $array
 * @return Array
 * @author Oliver Leisalu
 */
function arrayFlipTrue( array $array ) {
	$flipped = array_flip( $array );
	foreach( $flipped as &$value ) $value = true;
	return $flipped;
}

/**
 * Sort an array by keys using a "natural order" algorithm
 * 
 * @param array $array
 */
function natksort( array &$array ) {
	$values = array_keys( $array );
	natsort( $values );
	$new = array();
	foreach( $values as $key ) 
		$new[$key] = $array[$key];
	$array = $new;
}


if( !function_exists('get_called_class') ) {
/**
 * Return called class name
 * Usage:
 * <code>
class A {
	public static function staticMethod() {
		echo get_called_class();
	}
}
class B {

}
B::staticMethod(); // B
A::staticMethod(); // A
</code>
 * @author Michael Grenier
 * @param int $i_level optional
 * @return String
 */
function get_called_class ($i_level = 1) {
	$a_debug = debug_backtrace();

	$a_called = array();
	$a_called_function = $a_debug[$i_level]['function'];
	
	for ($i = 1, $n = sizeof($a_debug); $i < $n; $i++) {
		
		if (in_array($a_debug[$i]['function'], array('eval')) ||
			strpos($a_debug[$i]['function'], 'eval()') !== false)
			continue;
		
		if (in_array($a_debug[$i]['function'], array('__call', '__callStatic')))
			$a_called_function = $a_debug[$i]['args'][0];
		
		if (in_array($a_debug[$i]['function'], array('call_user_func', 'call_user_func_array')) && $a_debug[$i]['args'][0][1] == $a_called_function)
			return $a_debug[$i]['args'][0][0];
		
		if ($a_debug[$i]['function'] == $a_called_function)
			$a_called = $a_debug[$i];
				
	}
	
	if (isset($a_called['object']) && isset($a_called['class']))
		return (string)$a_called['class'];
	
	$i_line = (int)$a_called['line'] - 1;
	$a_lines = explode("\n", file_get_contents($a_called['file']));
	
	preg_match("#([a-zA-Z0-9_]+){$a_called['type']}{$a_called['function']}( )*\(#", $a_lines[$i_line], $a_match);
	
	unset($a_debug, $a_called, $a_called_function, $i_line, $a_lines);
	
	if (sizeof($a_match) > 0)
		$s_class = (string)trim($a_match[1]);
	else
		$s_class = (string)$a_called['class'];
	
	if ($s_class == 'self')
		return get_called_class($i_level + 2);
		
	return $s_class;
	
} 
} // if

/**
 * Sort all elements into an array where each parent is follewed by its children.
 * Sample
 * <code>
$input = array( 
	array('id'=>3, 'parent'=>2),
	array('id'=>1, 'parent'=>0),
	array('id'=>4, 'parent'=>0),
	array('id'=>2, 'parent'=>1),
);
$config = array(
	'idColumn'=>'id',
	'parentIdColumn'=>'parent',
	'addLevels' => true,
);
$result = sortToTree( $input, $config );
// Result is ordered like this:
array( 
	array('id'=>1, 'parent'=>0, 'level'=>0),
	array('id'=>2, 'parent'=>1, 'level'=>1),
	array('id'=>3, 'parent'=>2, 'level'=>2),
	array('id'=>4, 'parent'=>0, 'level'=>0),
);
</code>
Default config
<code>
$defaultConfig = array(
	'idColumn' => 'id',
	'parentIdColumn' => 'parent',
	'addLevels' => false,
	'levelVar' => 'level',
);
</code>
 *
 * @param array $elements
 * @param array $config
 */
function sortToTree( array &$elements, array $config = array()) {
	
	$defaultConfig = array(
		'idColumn' => 'id',
		'parentIdColumn' => 'parent',
		'addLevels' => false,
		'levelVar' => 'level',
	);
	$config = arrayMerge( $defaultConfig, $config );

	$tree = array();
	$roots = array();
	foreach( $elements as $i => $e ) {
		
		if( is_object($e) ) {
			$id = $e->$config['idColumn'];
			$parentId = $e->$config['parentIdColumn'];
		} else if( is_array($e) ) {
			$id = $e[$config['idColumn']];
			$parentId = $e[$config['parentIdColumn']];
		}

		if( $parentId instanceof DomArObject ) {
			$parentId = $parentId->id;
		}
		
		// add element to tree list
		$tree[$id]['index'] = $i;

		if( $parentId > 0 ) {
			// has parent, so its not root. 
			$tree[$parentId]['children'][] = &$tree[$id];
			
		} else {
			// if it doesn't have a parent, it might be a ROOT
			$roots[$id] = &$tree[$id];
		}
	}
	unset($tree);

	if( !function_exists('__sortToTreeHelper') ) {
		function __sortToTreeHelper( &$nodes, &$elements, &$config, &$resultList = array(), $lvl = 0 ) {

			foreach( $nodes as &$node ) {
				$element = $elements[$node['index']];
				
				if( $config['addLevels'] === true ) {
					if( is_array($element) )
						$element[$config['levelVar']] = (int)$lvl;
					elseif( is_object($element) )
						$element->{$config['levelVar']} = (int)$lvl;
				}
				
				$resultList[] = $element;
				
				if( $node['children'] )
					__sortToTreeHelper( $node['children'], $elements, $config, $resultList, $lvl+1 );
			}
			return $resultList;
		}
	}
	return __sortToTreeHelper( $roots, $elements, $config );
}
?>